home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
math
/
alged34.zip
/
ALGEDSRC.ZIP
/
ALGFILE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-06
|
14KB
|
525 lines
/*--------------------------------------------------------------------
Alged: Algebra Editor henckel@vnet.ibm.com
Copyright (c) 1994 John Henckel
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies.
*/
#include "alged.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The following functions relate to reading and writing data files.
*/
#define push(tt) do { tt->next = tos; tos = tt; } while(0)
#define pop(tt) do { tt=tos; \
if (!tos) printf(msg[1]); else tos=tos->next; } while(0)
#define pushr(tt) do { tt->next = r; r = tt; } while(0)
#define popr(tt) do { tt=r; \
if (!r) printf(msg[2]); else r=r->next; } while(0)
/* = f + - * / ^ V N ? ( ) , used by infix read/write */
int wpr[10] = { 0,8,2,2,4,4,6,8,8,8 };
int rpr[15] = { 0,1,2,2,4,4,6,8,8,8,1,2,2 };
/* start-paren and end-paren, these are used as pseudo tokens. */
#define SPA 10
#define EPA 11
#define CMA 12
#define coper "=()+-*/^,"
#define numer "0123456789."
static char txt[2000];
char gdriver[80] = ""; // these three lines are exported to algraph.c
int gmode,pst,psz;
double lightx=1,lighty=3,lightz=2; // light source location
static int stoe=0; // see note in writetree
/*-----------------------------------------------------------------
parse option
*/
void parse_option(FILE *f, char *b) {
int i=0; double t;
switch (*b) {
case 's': fscanf(f,"%d",&bold1); break;
case 'i': fscanf(f,"%d",&bold2); break;
case 'c': fscanf(f,"%d",&norm); break;
case 'm': fscanf(f,"%d",&mcolor); break;
case 'e': fscanf(f,"%d",&sigdig); break;
case 'd': fscanf(f,"%lg",&maxrat); break;
case 'p': fscanf(f,"%d",&maxpow); break;
case 'a': fscanf(f,"%d",&ch8); break;
case 'v': fscanf(f,"%d",&i); directvideo=(i>0); break;
case 'y': fscanf(f,"%d",&yadj); break;
case '.': fscanf(f,"%d",&point); break;
case 'l': fscanf(f,"%3s",lang); break;
case 'f': fscanf(f,"%d",&postfix); break;
case 'g': fscanf(f,"%s %d %d %d",gdriver,&gmode,&pst,&psz); break;
case 'r': fscanf(f,"%lg %lg %lg",&lightx,&lighty,&lightz);
t = hypot(lightx,hypot(lighty,lightz));
if (t < 1E-20) lighty=1;
else { lightx/=t; lighty/=t; lightz/=t; }
break;
}
}
/*-----------------------------------------------------------------
get one token from the file
if nn=1 then negative signs are treated as operators.
*/
node *gettoken(FILE *f,int nn) {
int c,i;
static char buf[80];
double t;
node *p;
do {
c = fgetc(f);
if (c==';') do { c=fgetc(f); } while (c>0 && c!=10);
if (c=='?') {
fscanf(f,"%s",buf);
parse_option(f,buf);
c=0;
}
else if (c=='"') {
i = strlen(txt);
/* txt[i]=c;
fgets(txt+i+1,sizeof txt-i-2,f); */
fgets(txt+i,sizeof txt-i-1,f);
strcat(txt,"\r"); c=0;
}
else if (c=='@') {
fscanf(f,"%s",buf);
p = newvar(buf);
p->kind = FUN;
return p;
}
else if (c<0) return NULL; /* EOF */
} while (c<=' ');
if (c=='*') return newoper(MUL);
if (c=='/') return newoper(DIV);
if (c=='^') return newoper(EXP);
if (c==')') return newoper(EPA);
if (c=='(') return newoper(SPA);
if (c=='=') return newoper(EQU);
if (c=='+') return newoper(ADD);
if (c==',') return newoper(CMA);
if (c=='-') {
if (nn) return newoper(SUB);
c = fgetc(f); /* look ahead */
ungetc(c,f);
if (strchr(numer,c)) { t=0;
fscanf(f,"%lg",&t);
return newnum(-t);
}
else {
printf(msg[34]); pause; // unary minus warning
return newnum(-1);
}
}
if (strchr(numer,c)) {
ungetc(c,f);
fscanf(f,"%lg",&t);
return newnum(t);
}
i = 0;
buf[i++] = c;
while (i<25) {
c=fgetc(f);
if (strchr(coper,c)) {
if (c=='(') {
p=newnode();
p->kind=FUN;
buf[i]=0;
strcpy(p->name,buf);
p->nump = 1;
return p;
}
ungetc(c,f); break;
}
if (c<=' ') break;
buf[i++] = c;
}
buf[i]=0;
if (!strcmp(buf,"e")) return newnum(M_E);
if (!strcmp(buf,"pi")) return newnum(M_PI);
return newvar(buf);
}
/*-----------------------------------------------------------------
load infix expression
*/
node *loadinfix(char *filename) {
FILE *f;
node *tos,*p,*r,*t;
int i,y; /* y == previous was a num or var */
f = fopen(filename,"r");
if (f==NULL) {
printf(msg[3],filename);
pause;
return NULL;
}
tos = r = NULL;
*txt = y = 0;
p = gettoken(f,y);
while (p) {
if (*txt && p->kind<=NUM) {
p->msg = malloc(strlen(txt)+1);
strcpy(p->msg,txt);
*txt = 0;
}
if (y && (rpr[p->kind]==8 || rpr[p->kind]==1)) /* NEW EXPRESSION */
while (r) { /* REDUCE ALL */
popr(t);
if (t->kind > EXP) continue;
t->nump = 2;
pop(t->rt);
pop(t->lf);
if (t->lf->msg) {
t->msg = t->lf->msg;
t->lf->msg = NULL;
}
push(t);
}
if (rpr[p->kind]==1) { /* FUNC or StartPAREN */
pushr(p);
y=0;
}
else if (rpr[p->kind]==8) { /* VAR and NUM */
push(p);
y=1;
}
else if (r && rpr[p->kind] <= rpr[r->kind] &&
p->kind != EXP) { /* REDUCE */
popr(t);
if (t->kind > EXP) continue;
t->nump = 2;
pop(t->rt);
pop(t->lf);
if (t->lf->msg) {
t->msg = t->lf->msg;
t->lf->msg = NULL;
}
push(t);
continue; /* don't get more input */
}
else if (r && r->kind==FUN && p->kind==CMA) { /* COMMA */
r->nump++;
freenode(p);
y=0;
}
else if (r && r->kind==FUN && p->kind==EPA) { /* END OF FUNCTION */
popr(t);
if (t->nump>MAXP) t->nump = MAXP;
for (i=t->nump; i--; ) pop(t->parm[i]);
if (t->lf->msg) {
t->msg = t->lf->msg;
t->lf->msg = NULL;
}
push(t);
freenode(p); /* free close paren */
y=1;
}
else if (r && r->kind==SPA && p->kind==EPA) { /* MATCH PARENS */
popr(t);
freenode(t);
freenode(p);
y=1;
}
else {
if (p->kind > EXP) {
printf(msg[4]);
pause;
}
else pushr(p); /* SHIFT */
y=0;
}
p = gettoken(f,y);
}
while (r) { /* REDUCE all remaining oper */
popr(t);
if (t->kind > EXP) continue;
t->nump = 2;
pop(t->rt);
pop(t->lf);
if (t->lf->msg) {
t->msg = t->lf->msg;
t->lf->msg = NULL;
}
push(t);
}
fclose(f);
return tos;
}
/*--------------------------------------------------------------------
load a sample expression
*/
node *load(char *filename) {
FILE *f;
static char tok[80];
node *tos,*p;
int i;
double t;
f = fopen(filename,"r");
if (f==NULL) {
printf(msg[5],filename);
pause;
return NULL;
}
tos = NULL;
*txt = 0;
while (1) {
if (1 != fscanf(f,"%24s",tok)) break;
if (tok[0]==';') {
fgets(tok,sizeof tok,f);
continue;
}
if (tok[0]=='"') {
strcat(txt,tok+1); i=strlen(txt);
fgets(txt+i,sizeof txt-i-2,f);
strcat(txt,"\r");
continue;
}
if (*tok=='?') { /* --- Options ---- */
parse_option(f,tok+1);
continue;
}
if (*tok=='*') { /* ------------------ */
p = newoper(MUL);
pop(p->rt);
pop(p->lf);
push(p);
}
else if (*tok=='=') { /* ------------------ */
p = newoper(EQU);
pop(p->rt);
pop(p->lf);
push(p);
}
else if (*tok=='+